using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; // Required for RawImage

public class PlaceUiAboveObject : MonoBehaviour
{
    [Header("Cameras")]
    public Camera paiCamera;        // 渲染3D棋牌到RenderTexture的相机
    public Camera uiCamera;         // Canvas (ScreenSpace-Camera) 使用的UI相机

    [Header("Object & UI Elements")]
    public GameObject paiObject;    // 3D棋牌对象
    public RawImage rawImageDisplay; // 显示RenderTexture的RawImage组件
    public RectTransform uiImageToPlace; // 要放置在棋牌上方的UI Image的RectTransform

    [Header("Positioning Offset")]
    public Vector3 worldOffset = Vector3.zero; // 在棋牌对象本地坐标系中的偏移量 (例如，向上偏移到顶部)
                                               // 或者 public float heightOffset = 0.5f; 来动态计算

    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void LateUpdate() // 使用 LateUpdate 确保棋牌对象的位置已经更新完毕
    {
        if (paiCamera == null || uiCamera == null || paiObject == null || rawImageDisplay == null || uiImageToPlace == null)
        {
            Debug.LogWarning("PlaceUiAboveObject: 必要组件未在Inspector中指定。");
            return;
        }

        // 1. 计算3D棋牌对象在世界中的目标位置 (考虑偏移量)
        Vector3 targetWorldPosition = paiObject.transform.position;
        if (worldOffset != Vector3.zero)
        {
            targetWorldPosition += paiObject.transform.TransformDirection(worldOffset);
        }
        //  示例: 如果想根据包围盒获取顶部中心点 (可能需要Renderer组件)
        //  Renderer objectRenderer = paiObject.GetComponent<Renderer>();
        //  if (objectRenderer != null)
        //  {
        //      targetWorldPosition = objectRenderer.bounds.center + new Vector3(0, objectRenderer.bounds.extents.y, 0);
        //  }


        // 2. 将世界位置转换到 paiCamera 的屏幕/视口坐标
        Vector3 paiCamScreenPos = paiCamera.WorldToScreenPoint(targetWorldPosition);

        // 检查对象是否在 paiCamera 的前方
        if (paiCamScreenPos.z < 0)
        {
            uiImageToPlace.gameObject.SetActive(false); // 对象在相机后面，隐藏UI元素
            return;
        }
        uiImageToPlace.gameObject.SetActive(true);

        // 3. 将 paiCamera 屏幕坐标转换为UV坐标 (0-1范围，左下角为0,0)
        float u = paiCamScreenPos.x / paiCamera.pixelWidth;
        float v = paiCamScreenPos.y / paiCamera.pixelHeight;

        // （可选）检查UV是否在有效范围内 (0到1)
        // 如果对象部分或完全在 paiCamera 视锥外，UV可能会超出0-1。
        // 根据需求决定是否要隐藏或固定 uiImageToPlace。
        if (u < 0 || u > 1 || v < 0 || v > 1)
        {
            //  可以选择隐藏，或者将其固定在RawImage的边缘
            // uiImageToPlace.gameObject.SetActive(false);
            // return;
        }
        u = Mathf.Clamp01(u); // 将UV限制在0-1，如果超出则贴边
        v = Mathf.Clamp01(v);


        // 4. 计算UV坐标在 RawImage 上的局部坐标 (相对于RawImage的pivot)
        Rect rawImageRect = rawImageDisplay.rectTransform.rect;
        Vector2 localPointOnRawImage = new Vector2(
            rawImageRect.x + u * rawImageRect.width,
            rawImageRect.y + v * rawImageRect.height
        );

        // 5. 将 RawImage 上的局部点转换为世界坐标
        Vector3 worldPointOnRawImageSurface = rawImageDisplay.transform.TransformPoint(localPointOnRawImage);

        // 6. 将此世界点转换为 uiCamera 的屏幕坐标
        //    对于ScreenSpace-Camera模式的Canvas，uiCamera是Canvas组件上指定的Render Camera
        Vector2 screenPointForUiImage = RectTransformUtility.WorldToScreenPoint(uiCamera, worldPointOnRawImageSurface);

        // 7. 将屏幕坐标转换为 uiImageToPlace 父对象的局部坐标，并设置其 anchoredPosition
        RectTransform parentRectTransform = uiImageToPlace.parent as RectTransform;
        if (parentRectTransform == null)
        {
            Debug.LogError("uiImageToPlace 必须有一个 RectTransform 父对象。");
            return;
        }

        Vector2 localPointInParent;
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(
                parentRectTransform,
                screenPointForUiImage,
                uiCamera, // 对于 ScreenSpace-Camera，这是渲染Canvas的相机
                out localPointInParent
            ))
        {
            uiImageToPlace.anchoredPosition = localPointInParent;
        }
        else
        {
            // 如果转换失败（例如，点在相机后方或发生其他错误），可以选择隐藏UI
            // uiImageToPlace.gameObject.SetActive(false);
            Debug.LogWarning("无法将屏幕点转换为 uiImageToPlace 父对象的局部坐标。");
        }
    }
}
